package eu.livotov.jsms.impl;

import com.logica.smpp.*;
import com.logica.smpp.pdu.*;
import eu.livotov.jsms.SMSException;
import eu.livotov.jsms.SMSMessage;
import eu.livotov.jsms.SMSProvider;
import eu.livotov.jsms.util.CryptoTool;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: dlivotov
 * Date: 14.04.12
 * Time: 23:27
 * To change this template use File | Settings | File Templates.
 */
public class SMPPProvider implements SMSProvider
{

    public final static int SMPP_PORT = 2205;

    private String smsCenterAddress = "";
    private int smsCenterPort = 2205;
    private String smsCenterLogin = "";
    private String smsCenterPassword = "";
    private String smsCenterSystemType = "";

    public SMPPProvider(String smppHost, int smppPort, String smppLogin, String smppPassword, String smppSystemType)
    {
        this.smsCenterAddress = smppHost;
        this.smsCenterPort = smppPort;
        this.smsCenterLogin = CryptoTool.encryptString(smppLogin);
        this.smsCenterPassword = CryptoTool.encryptString(smppPassword);
        this.smsCenterSystemType = smppSystemType;
    }

    public String getName()
    {
        return "Generic SMPP gateway provider. Can send sms messages via any SMPP-compatible gateway.";
    }

    public SMSMessage sendMessage(final SMSMessage message)
    {
        try
        {
            Session session = openSession();

            for (String number : message.getNumbers())
            {
                SubmitSM request = new SubmitSM();
                request.setSourceAddr(message.getSender());
                request.setDestAddr(number);
                request.setShortMessage(message.getText(), Data.ENC_UTF16_BE);
                request.setDataCoding((byte) 0x08);
                session.submit(request);
            }

            closeSession(session);
        } catch (Throwable err)
        {
            err.printStackTrace();
            throw new SMSException(1, "Cannot deliver sms message: " + err.getMessage());
        }

        return message;
    }

    private Session openSession()
            throws PDUException, WrongSessionStateException, TimeoutException, IOException
    {
        Connection conn = new TCPIPConnection(smsCenterAddress, smsCenterPort);
        Session session = new Session(conn);

        BindRequest breq = new BindTransmitter();
        breq.setSystemId(CryptoTool.decryptString(smsCenterLogin));
        breq.setPassword(CryptoTool.decryptString(smsCenterPassword));
        breq.setSystemType(smsCenterSystemType);

        Response resp = session.bind(breq);

        if (resp.getCommandStatus() == Data.ESME_ROK)
        {
            return session;
        } else
        {
            throw new IOException("Cannot bind to sms center: " + resp.getCommandStatus());
        }
    }

    private void closeSession(Session session)
    {
        if (session != null)
        {
            try
            {
                session.unbind();
            } catch (Throwable err)
            {
                // n/a
            }
        }
    }

}
